package sfeir.ergosum.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import sfeir.ergosum.HiveActivity;
import sfeir.ergosum.R;
import sfeir.ergosum.dao.DatabaseConnection;
import sfeir.ergosum.dao.DatabaseProvider;
import sfeir.ergosum.dao.RemoteProvider;
import sfeir.ergosum.model.Contact;
import sfeir.ergosum.model.Person;
import sfeir.ergosum.model.spreadsheet.SpreadsheetEntry;
import sfeir.ergosum.tools.SpreadsheetClient;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import com.google.gdata.data.TextContent;
import com.google.gdata.data.spreadsheet.CellEntry;
import com.google.gdata.data.spreadsheet.CellFeed;

/**
 */
public class BackUpService extends Service {
    public static final String ACTION_BACKUP = "sfeir.ergosum.intent.action.BACKUP_SERVICE_BACKUP";
    public static final String ACTION_RESTORE = "sfeir.ergosum.intent.action.BACKUP_SERVICE_RESTORE";

    // variable which controls the notification thread

    private SharedPreferences mPrefs;
    protected boolean mFinished;
    private SpreadsheetClient mSpreadsheetClient;
    private String mKey;
    private static Context mContext;
    private NotificationManager mNM;

    public static void actionBackup(Context context) {
        mContext = context;
        Intent i = new Intent();
        i.setClass(context, BackUpService.class);
        i.setAction(BackUpService.ACTION_BACKUP);
        context.startService(i);
    }

    public static void actionRestore(Context context, String key) {
        mContext = context;
        Intent i = new Intent();
        i.setClass(context, BackUpService.class);
        i.setAction(BackUpService.ACTION_RESTORE);
        i.putExtra("key", key);
        context.startService(i);
    }

    @Override
    public void onCreate() {
        Log.d("ErgoSum", "*** Create ErgoSum Backup service");
        super.onCreate();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        Log.d("ErgoSum", "*** Start ErgoSum Backup service");
        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        if (ACTION_BACKUP.equals(intent.getAction())) {
            Log.d("ErgoSum", "*** Start Backup");
            Toast.makeText(BackUpService.this, R.string.backup_start, 500)
                    .show();
            mTaskBackup.run();
            /*
             * Thread notifyingThread = new Thread(null, mTaskBackup,
             * "BackUpService"); mCondition = new ConditionVariable(false);
             * //notifyingThread.start();
             */

        } else if (ACTION_RESTORE.equals(intent.getAction())) {
            Log.d("ErgoSum", "*** Start Restore");
            Toast.makeText(BackUpService.this, R.string.backup_restore_start,
                    500).show();
            if (intent.hasExtra("key"))
                mKey = intent.getStringExtra("key");
            //runTaskRestore();
            mTaskRestore.run();
            /*
             * Thread notifyingThread = new Thread(null, mTaskRestore,
             * "BackUpService"); mCondition = new ConditionVariable(false);
             * notifyingThread.start();
             */
        }
    }

    
    private Runnable mTaskBackup = new Runnable() { public void run() {
     
    //protected void runTaskBackup() {
        mPrefs = getSharedPreferences(getPackageName() + "_preferences",
                MODE_WORLD_READABLE);
        DatabaseProvider dp = new DatabaseProvider(new DatabaseConnection(
                BackUpService.this));
        dp.open();
        List<Contact> list = dp.getAllContacts();
        dp.close();
        final Map<String, String> map = new HashMap<String, String>();
        for (Contact contact : list) {
            map.put(contact.getUrl(), contact.getAlias());
        }
        final int number = list.size();
        mSpreadsheetClient = new SpreadsheetClient(
                new SpreadsheetClient.ResponseHandler() {
                    @Override
                    public void handleMessage(Message msg) {
                        if (mFinished)
                            return;
                        switch (msg.what) {
                        case R.id.httpclient_ready:
                            Log.d("ErgoSum", "HTTPClient ready");

                            String ids = mPrefs.getString(
                                    "preference_loginpassKey", " \n ");
                            String[] values;
                            values = ids.split("\n");

                            mSpreadsheetClient.setUserCredentials(values[0],
                                    values[1]);
                            // mSpreadsheetClient.setUserCredentials(mPrefs.getString(
                            // "preference_login_name", ""), mPrefs.getString(
                            // "preference_login_pass", ""));
                            mSpreadsheetClient.handler.obtainMessage(
                                    R.id.request_login,
                                    R.id.client_auth_writely, 0, "writely")
                                    .sendToTarget();
                            break;
                        case R.id.client_get_spreadsheets:
                            Log.d("ErgoSum", "Client get spreadsheets");
                            break;
                        case R.id.client_auth_success:
                            Log.d("ErgoSum", "Auth success");

                            break;
                        case R.id.client_auth_writely:
                            Log.d("ErgoSum", "Client Auth writely");
                            mSpreadsheetClient.handler.obtainMessage(
                                    R.id.request_new_backup_spreadsheet, map)
                                    .sendToTarget();
                            break;
                        case R.id.client_new_backup_spreadsheet:
                            SpreadsheetEntry entry = (SpreadsheetEntry) msg.obj;
                            String key = entry.getId();
                            key = key.substring(key
                                    .lastIndexOf("spreadsheet%3A") + 14);
                            mPrefs.edit().putString("backup_spreadsheet_key",
                                    key).commit();

                            showNotification(getString(R.string.backup_stop, number));
                            //Toast.makeText(BackUpService.this, R.string.backup_stop, 500).show();
                            mSpreadsheetClient.terminate();
                            BackUpService.this.stopSelf();
                            break;
                        default:
                            super.handleMessage(msg);
                            break;
                        }
                    }
                });
        mSpreadsheetClient.start();
        // Connect to the spreadsheet

       
          } 
    };
    

     private Runnable mTaskRestore = new Runnable() { public void run() {
     
    //protected void runTaskRestore() {
        mPrefs = getSharedPreferences(getPackageName() + "_preferences",
                MODE_WORLD_READABLE);
        mSpreadsheetClient = new SpreadsheetClient(
                new SpreadsheetClient.ResponseHandler() {
                    @Override
                    public void handleMessage(Message msg) {
                        if (mFinished)
                            return;
                        switch (msg.what) {
                        case R.id.httpclient_ready:
                            Log.d("ErgoSum", "HTTPClient ready");
                            String ids = mPrefs.getString(
                                    "preference_loginpassKey", " \n ");
                            String[] values = new String[2];
                            values = ids.split("\n");

                            mSpreadsheetClient.setUserCredentials(values[0],
                                    values[1]);
                            mSpreadsheetClient.handler.obtainMessage(
                                    R.id.request_login,
                                    R.id.client_auth_success, 0, "wise")
                                    .sendToTarget();
                            break;
                        case R.id.client_get_spreadsheets:
                            Log.d("ErgoSum", "Client get spreadsheets");
                            break;
                        case R.id.client_auth_success:
                            Log.d("ErgoSum", "Auth success");
                            String key = mKey;
                            if (key == null)
                                key = mPrefs.getString(
                                        "backup_spreadsheet_key", null);
                            if (key == null) {
                                Toast.makeText(BackUpService.this,
                                        R.string.backup_restore_no_backup, 500)
                                        .show();
                                mSpreadsheetClient.terminate();
                                BackUpService.this.stopSelf();
                            } else
                                mSpreadsheetClient.handler.obtainMessage(
                                        R.id.request_restore_spreadsheet, key)
                                        .sendToTarget();

                            break;
                        case R.id.client_restore_spreadsheet:
                            CellFeed entry = (CellFeed) msg.obj;
                            if (entry != null) {
                                int number = restoreContact(entry);
                                showNotification(getString(R.string.backup_restore_stop, number));
                                mSpreadsheetClient.terminate();
                                HiveActivity.startActivity(mContext, "", "");
                                BackUpService.this.stopSelf();
                            }

                            break;
                        default:
                            super.handleMessage(msg);
                            break;
                        }
                    }
                });
        mSpreadsheetClient.start();
        
          } 
     };
         
    

    protected int restoreContact(CellFeed entry) {
        DatabaseConnection dbCon = new DatabaseConnection(
                BackUpService.this);
        int number = 0;
        //RemoteProvider dao = new RemoteProvider(dbCon);
        DatabaseProvider db = new DatabaseProvider(dbCon);
        try {
            db.open();
            String alias = null;
            String url = null;
            for (CellEntry le : entry.getEntries()) {
                TextContent content = (TextContent) le.getContent();
                String value = content.getContent().getPlainText();
                if (value.toLowerCase().equals("alias")
                        || value.toLowerCase().equals("url")) {
                    continue;
                }
                if (alias == null) {
                    alias = value;
                } else {
                    url = value;
                    Log.d("ErgoSum", alias + " : " + value);
                    Person p = RemoteProvider.getUpdatedPerson(url);
                    if (p != null) {
                        Contact c = db.getContactByURL(url);
                        if (c == null) {
                            c = new Contact(alias, url);
                            c.setPerson(p);
                            db.addContact(c);
                        }
                        else {
                            c.setPerson(p);
                            c.setAlias(alias);
                            db.updateFullContactWithTimestamp(c);
                        }
                        number++;
                    }
                    alias = null;
                    url = null;                             
                }
            }
        }
        finally {
            db.close();
        }
        return number;
    }

    
    private void showNotification(String string) {
        // Set the icon, scrolling text and timestamp.
        // Note that in this example, we pass null for tickerText. We update the
        // icon enough that
        // it is distracting to show the ticker text every time it changes. We
        // strongly suggest
        // that you do this as well. (Think of of the "New hardware found" or
        // "Network connection
        // changed" messages that always pop up)

        Notification notification = new Notification(R.drawable.notification, string, System.currentTimeMillis());

        Intent intent = new Intent(this, HiveActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        // The PendingIntent to launch our activity if the user selects this
        // notification
        PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, 0);

        // Set the info for the views that show in the notification panel.
        notification.setLatestEventInfo(this, string, string, contentIntent);

        // Send the notification.
        // We use a layout id because it is a unique number. We use it later to
        // cancel.
        mNM.notify(42, notification);
    }
    
    public static String getACTION_BACKUP() {
        return ACTION_BACKUP;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        // mNM.cancel(MOOD_NOTIFICATIONS);
        // Stop the thread from generating further notifications
        mFinished = true;
    }

    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }

    private final IBinder binder = new MyBinder();

    public class MyBinder extends Binder {
        BackUpService getService() {
            return BackUpService.this;
        }
    }
}